<?php

namespace app\service;

use app\exception\ErrnoPlus;
use app\model\UrlDomainConfModel;
use app\model\UrlDomainRelationModel;
use share\exception\ApiException;
use share\service\BaseModelService;
use share\service\IdMakerService;
use share\utils\Helper;

class UrlDomainRelationService extends BaseModelService
{
    /**
     * 单例的
     */
    CONST URL_SELECTOR_TYPE_SINGLE = 1;

    /**
     * 组合的
     */
    CONST URL_SELECTOR_TYPE_MUTIL = 2;

    public static function getModel()
    {
        return new UrlDomainRelationModel;
    }

    public static function getAllRelation(){
        $domain = UrlDomainService::getAllByFilter([]);
        $relation = self::getAllByFilter([]);
        $selector = UrlSelectorService::getAllByFilter([]);
        return [
            'domain' => $domain,
            'relation' => $relation,
            'selector' => $selector,
        ];
    }

    public static function getRelationByDomain(){
        $data = self::getAllRelation();
        $relation = $data['relation'];
        $selector = $data['selector'];

        $res = [];
        foreach($data['domain'] as $domain){
            $tmp = $domain;
            $tmpRelation =  Helper::filter($relation,['url_domain_id' => $domain['id']]);
            if($tmpRelation){
                $tmp['selector'] = [];
                foreach($tmpRelation as $rel){
                    $selectorId = $rel['url_selector_id'];
                    $selectorType = $rel['url_selector_type'];
                    if($selectorType == self::URL_SELECTOR_TYPE_MUTIL){
                        $tmp['selector'] =  Helper::filter($selector,['group_id' => $selectorId]);
                    }
                    else{
                        $tmp['selector'] =  Helper::filter($selector,['id' => $selectorId]);
                    }
                }
            }
            $res[] = $tmp;
        }
        return $res;
    }

    public static function getRelationBySelector(){
        $data = self::getAllRelation();
        $relation = $data['relation'];
        $selector = $data['selector'];
        $domain = $data['domain'];
        $group = [];
        $groupIds = array_filter(Helper::arraySmartUnique(array_column($selector,'group_id')));
        foreach($groupIds as $id){
            $children = Helper::filter($selector,['group_id' => $id]);
            if($children){
                $group[$id] = $children;
            }
        }
        $res = [
            'domain' => $domain,
        ];    
        $formatSelector = [];
        foreach($selector as $item){
            $tmp = $item;
            $relationId = $item['group_id'] > 0 ? $item['group_id'] : $item['id'];
            $relationType = $item['group_id'] > 0 ? self::URL_SELECTOR_TYPE_MUTIL : self::URL_SELECTOR_TYPE_SINGLE;
            $relations = Helper::filter($relation,['url_selector_id' => $relationId,'url_selector_type' => $relationType]);
            foreach($relations as $re){
                $key = UrlConfigService::getDomainTypeNameByIndex($re['domain_type']);
                $tmp[$key] = $re['url_domain_id'];
            }
            $formatSelector[] = $tmp;
        }
        $res['selector'] = $formatSelector;
        return $res;
    }


    /**
     * 删除条目
     */
    public static function delById($id)
    {
        $origin = self::getBase($id);
        if (empty($origin)) {
            return;
        }
        //TODO  add code here  
        $res = self::del($id);
        return $res;
    }

    public static function getPriorityBySelector($selector){
        $score = 0;
        foreach($selector as $item){
            $score += UrlSelectorService::getScoreByType($item['key']);
        }       
        return $score;
    }

    
    /**
     * 删除筛选器
     */
    public static function delBySelector($id)
    {
        $selector = UrlSelectorService::getBase($id);
        if($selector){
            if($selector['group_id'] != 0){
                UrlSelectorService::delByFilter([
                    'group_id' => $selector['group_id']
                ]);
                self::delByFilter([
                    'url_selector_id' => $selector['group_id'],
                    'url_selector_type' => self::URL_SELECTOR_TYPE_MUTIL,
                ]);
            }
            else{                
                UrlSelectorService::del($id);
                self::delByFilter([
                    'url_selector_id' => $id,
                    'url_selector_type' => self::URL_SELECTOR_TYPE_SINGLE,
                ]);
            }
            UrlConfigService::deleteCache();
        }
    }

    /**
     * 通过筛选器分配映射关系
     */
    public static function allocBySelector($data)
    {
        $id = $data['id'];
        if($id == 0){
            self::addSelectorToRelation($data);
        }
        else{
            self::setSelectorToRelation($data);
        }
        UrlConfigService::deleteCache();
    }

    /**
     * 检查筛选器的数据是否可用
     */
    public static function checkCurrentSelectorDetailInfo($selector){
        $selectorTypes = UrlConfigService::getDescSelectorTypeList();        
        $selectorKeys = array_keys($selectorTypes);
        $existTypes = [];
        foreach($selector as $select){
            $key = $select['key'];
            if(isset($existTypes[$key])){
                return false;
            }
            if(!in_array($key,$selectorKeys)){
                return false;
            }
        }
        return true;
    }

    /**
     * 检查筛选器的域名信息是否可用
     */
    public static function checkCurrentSelectorDomainIds($data){ 
        $domainTypes = UrlConfigService::getDescDomainTypeList();
        $domainKeys = array_keys($domainTypes);
        $ids = [];
        foreach($domainKeys as $key){
            if(isset($data[$key])){
                $ids[] = $data[$key];
            }
        }
        if(count($ids) != count($domainKeys)){
            return false;
        }
        $domains = UrlDomainService::getAll($ids);
        if(count($domains) != count($domainKeys)){
            return false;
        }
        return $ids;
    }

    /**
     * 通过筛选器添加映射关系
     */
    public static function addSelectorToRelation($data){
        $selector = $data['selector'];
        if(!self::checkCurrentSelectorDetailInfo($selector)){
            throw new ApiException("selected item error",ErrnoPlus::INVALID_PARAM);
        }
        if(!self::checkCurrentSelectorDomainIds($data)){
            throw new ApiException("selected domain error",ErrnoPlus::INVALID_PARAM);
        }  
        self::_addSelector($data);  
    }

    protected static function _addSelector($data){
        $selector = $data['selector'];
        $relationId = 0;
        $relationType = self::URL_SELECTOR_TYPE_SINGLE;
        $tn = time();
        if(count($selector) > 1){
            $groupId = IdMakerService::make(IdMakerService::NAME_OF_URL_SELECTOR_GROUP);
            $relationId = $groupId;
            $relationType = self::URL_SELECTOR_TYPE_MUTIL;
            $items = [];            
            $ids = IdMakerService::makeMutil(IdMakerService::NAME_OF_URL_SELECTOR,count($selector));
            $i = 0;
            foreach($selector as $select){
                $items[] = [
                    'id' => $ids[$i],
                    'type' => $select['key'],
                    'value' =>  $select['value'],
                    'group_id' => $groupId,
                    'created' => $tn,
                ];
                $i++;
            }
            UrlSelectorService::addBulk($items);
        }
        else{
            $relationId = IdMakerService::make(IdMakerService::NAME_OF_URL_SELECTOR);
            UrlSelectorService::add([
                'id' => $relationId,
                'type' => $selector[0]['key'],
                'value' =>  $selector[0]['value'],
                'group_id' => 0,
                'created' => $tn,
            ]);
        }
        $priority = self::getPriorityBySelector($selector);
        $relationInfos = [];
        $domainTypes = UrlConfigService::getDescDomainTypeList();
        $domainKeys = array_keys($domainTypes);
        foreach($domainKeys as $key){
            $relationInfos[] = [
                'url_domain_id' => $data[$key],
                'domain_type' => UrlConfigService::getDomainTypeIndexByName($key),
                'url_selector_id' => $relationId,
                'url_selector_type'  => $relationType,
                'priority' => $priority,
                'created' => $tn,
            ];
        }
        self::addBulk($relationInfos);
    }

    /**
     * 通过筛选器设置映射关系
     */
    public static function setSelectorToRelation($data){
        // 暂时简单处理 删除所有原始信息后 重新添加
        $selector = $data['selector'];
        if(!self::checkCurrentSelectorDetailInfo($selector)){
            throw new ApiException("selected item error",ErrnoPlus::INVALID_PARAM);
        }
        if(!self::checkCurrentSelectorDomainIds($data)){
            throw new ApiException("selected domain error",ErrnoPlus::INVALID_PARAM);
        }
        $groupId = isset($data['group_id']) ? $data['group_id'] : 0;
        if($groupId > 0){
            self::delByFilter([
                'url_selector_id' => $groupId,
                'url_selector_type' => self::URL_SELECTOR_TYPE_MUTIL,
            ]);
            UrlSelectorService::delByFilter([
                'group_id' => $groupId,
            ]);
        }
        else{
            self::delByFilter([
                'url_selector_id' => $data['id'],
                'url_selector_type' => self::URL_SELECTOR_TYPE_SINGLE,
            ]);
            UrlSelectorService::del($data['id']);
        }
        self::_addSelector($data);
    }

    /**
     * 页面查询条件
     */
    public static function buildCondition($filter)
    {
        $res = [];
        if (isset($filter['name']) && !empty($filter['name'])) {
            $res['name'] = ['like', '%' . $filter['name'] . '%'];
        }
        if (isset($filter['type']) && !empty($filter['type'])) {
            $res['type'] = $filter['type'];
        }
        //TODO  add code here  
        return $res;
    }
}
